using System;
using UnityEngine;
using UnityEngine.UI;

#if UNITY_EDITOR
#endif

public class WindowController : MonoBehaviour
{
    public bool isTransparent
    {
        get { return _isTransparent; }
        set { SetTransparent(value); }
    }
    [SerializeField, Tooltip("启动时设置为透明")]
    private bool _isTransparent = false;

    internal LibUniWinApi _uniWinCore;
    private IntPtr windowHandle = IntPtr.Zero;
    // 窗口状态变量
    private bool isMaximized = false;
    private bool isMinimized = false;

    // 保存窗口原始大小和位置，用于恢复窗口时使用
    private float originalX, originalY, originalWidth, originalHeight;

    // 记录最大化前的窗口状态，用于任务栏操作后恢复
    private bool wasMaximizedBeforeMinimize = false;

    // 显示窗口的命令参数
    private const int SW_SHOW = 5;
    private const int SW_HIDE = 0;
    private const int SW_MAXIMIZE = 3;
    private const int SW_MINIMIZE = 6;
    private const int SW_RESTORE = 9;
    private const uint SPI_GETWORKAREA = 0x0030; // 获取工作区参数

    // 拖拽相关
    private bool isDragging = false;
    private Vector2 dragStartMouseWindows;    // 指针按下时的屏幕坐标（Windows 坐标系）
    private Vector2 dragStartWindowPos;       // 窗口起始位置（与 UniWinCore.SetWindowPosition 使用的坐标系一致）

    void Awake()
    {
        _uniWinCore = new LibUniWinApi();
    }
    void Start()
    {
        ShowUI();
        InitializeWindowHandle();
    }

    private void InitializeWindowHandle()
    {
        // 获取当前进程的主窗口
        windowHandle = GetUnityMainWindowHandle();

        if (windowHandle == IntPtr.Zero)
        {
            Debug.LogWarning("无法获取窗口句柄");
        }
    }

    /// <summary>
    /// 获取Unity主窗口句柄
    /// </summary>
    /// <returns>窗口句柄</returns>
    private IntPtr GetUnityMainWindowHandle()
    {
        // 获取当前进程ID
        int processId = System.Diagnostics.Process.GetCurrentProcess().Id;

        // 用于存储找到的窗口句柄
        IntPtr hWnd = IntPtr.Zero;

        // 枚举所有窗口，找到属于当前进程的主窗口
        WinApi.EnumWindows((hWnd1, lParam) =>
        {
            ulong processIdWindow;
            WinApi.GetWindowThreadProcessId(hWnd1, out processIdWindow);

            if (processIdWindow == (ulong)processId && WinApi.IsWindowVisible(hWnd1))
            {
                hWnd = hWnd1;
                return false; // 找到窗口后停止枚举
            }

            return true; // 继续枚举
        }, IntPtr.Zero);

        return hWnd;
    }


    private void SetTransparent(bool transparent)
    {
#if !UNITY_EDITOR
            if (_uniWinCore != null)
            {
              EnableTransparent(transparent);
            }
#endif
    }

    /// <summary>
    /// 最大化窗口
    /// </summary>
    public void MaximizeWindow()
    {

        if (windowHandle != IntPtr.Zero)
        {
            WinApi.ShowWindow(windowHandle, SW_MAXIMIZE);
            isMaximized = true;
            isMinimized = false;
        }



        isMaximized = true;
        isMinimized = false;
        wasMaximizedBeforeMinimize = true;
    }

    /// <summary>
    /// 最小化窗口
    /// </summary>
    public void MinimizeWindow()
    {
        if (windowHandle != IntPtr.Zero)
        {
            WinApi.ShowWindow(windowHandle, SW_MINIMIZE);
            isMinimized = true;
            isMaximized = false; // 最小化时暂时标记为非最大化
        }
    }

    /// <summary>
    /// 统一的还原方法（同时兼容系统原生最大化和自定义最大化的还原）
    /// </summary>
    public void Restore()
    {
        if (windowHandle != IntPtr.Zero)
        {
            // 先执行系统还原
            WinApi.ShowWindow(windowHandle, SW_RESTORE);
            // 重置状态
            isMaximized = false;
            isMinimized = false;
        }
    }


    /// <summary>
    /// 将窗口居中显示
    /// </summary>
    public void CenterWindow()
    {
        if (_uniWinCore == null || !LibUniWinApi.IsActive())
        {
            Debug.LogWarning("UniWinCore 未初始化或未激活，无法居中窗口。");
            return;
        }

        // 获取当前显示器索引
        int monitorIndex = LibUniWinApi.GetCurrentMonitor();

        // 获取显示器区域
        Vector2 monitorPos, monitorSize;
        if (!GetMonitorRectangle(monitorIndex, out monitorPos, out monitorSize))
        {
            Debug.LogWarning("无法获取显示器信息，窗口无法居中。");
            return;
        }

        // 获取窗口大小
        Vector2 windowSize = Vector2.zero;
        LibUniWinApi.GetSize(out windowSize.x, out windowSize.y);

        // 计算居中位置
        float centerX = monitorPos.x + (monitorSize.x - windowSize.x) / 2f;
        float centerY = monitorPos.y + (monitorSize.y - windowSize.y) / 2f;

        // 设置窗口位置
        LibUniWinApi.SetPosition(centerX, centerY);
    }

    private void CloseWindow()
    {
#if UNITY_EDITOR
        // 编辑器下停止播放
        UnityEditor.EditorApplication.isPlaying = false;
#else
    // 真机或打包环境下退出
    Application.Quit();
#endif
    }

    /// <summary>
    /// 设置/取消透明
    /// </summary>
    /// <param name="isTransparent">是否透明</param>
    public void EnableTransparent(bool isTransparent)
    {
        // 编辑器无法透明或边框与普通情况不同，因此跳过
#if !UNITY_EDITOR
            LibUniWinApi.SetTransparent(isTransparent);
            LibUniWinApi.SetBorderless(isTransparent);
#endif
        this._isTransparent = isTransparent;
    }

    /// <summary>
    /// 获取显示器位置和大小
    /// </summary>
    /// <param name="index">显示器索引</param>
    /// <param name="position">显示器位置</param>
    /// <param name="size">显示器大小</param>
    /// <returns>是否成功获取</returns>
    public static bool GetMonitorRectangle(int index, out Vector2 position, out Vector2 size)
    {
        return LibUniWinApi.GetMonitorRectangle(index, out position.x, out position.y, out size.x, out size.y);
    }

    public Vector2 GetWindowPosition()
    {
        Vector2 pos = Vector2.zero;
        LibUniWinApi.GetPosition(out pos.x, out pos.y);
        return pos;
    }
    public void SetWindowPosition(Vector2 position)
    {
        LibUniWinApi.SetPosition(position.x, position.y);
    }

    public void Dispose()
    {
        // 最后恢复窗口状态会很显眼，因此尝试不恢复，所以注释掉
        //DetachWindow();

        // 替代 DetachWindow()
        LibUniWinApi.UnregisterDropFilesCallback();
        LibUniWinApi.UnregisterMonitorChangedCallback();
        LibUniWinApi.UnregisterWindowStyleChangedCallback();
    }

    // public Toggle 窗口;
    public Button 最大化, 最小化, 还原, 居中, 关闭;
    void ShowUI()
    {

        // 窗口.SetIsOnWithoutNotify(isTransparent);
        // 窗口?.onValueChanged.AddListener(val => isTransparent = val);


        最大化.onClick.AddListener(() =>
        {
            MaximizeWindow();
        });
        最小化.onClick.AddListener(() =>
        {
            MinimizeWindow();
        });
        还原.onClick.AddListener(() =>
        {
            Restore();
        });

        居中.onClick.AddListener(() =>
        {
            CenterWindow();
        });
        关闭.onClick.AddListener(() =>
        {
            CloseWindow();
        });
    }

    // ----------------- 拖拽 API ----------------

    // 开始拖拽：外部（Handle）调用
    public void BeginWindowDrag(Vector2 unityPointerPos)
    {
        if (_uniWinCore == null)
        {
            _uniWinCore = new();
        }

        var active = LibUniWinApi.IsActive();
        if (!active)
        {
            LibUniWinApi.AttachMyWindow();
            if (active)
            {
                Debug.LogWarning("BeginWindowDrag: UniWinCore 未激活，无法拖动窗口。");
                return;
            }
        }
        // 记录起始位置
        dragStartMouseWindows = unityPointerPos;

        isDragging = true;
    }

    public Vector2 windowPosition
    {
        get { return _uniWinCore != null ? GetWindowPosition() : Vector2.zero; }
        set { SetWindowPosition(value); }
    }

    // 拖拽中：外部（Handle）调用
    public void DragWindowTo(Vector2 unityPointerPos)
    {
        if (!isDragging || _uniWinCore == null || !LibUniWinApi.IsActive())
            return;

        // 使用系统光标位置和拖拽起点来计算窗口新位置，避免 Unity 屏幕坐标转换带来的抖动
        Vector2 currentCursor = Vector2.zero;
        LibUniWinApi.GetCursorPosition(out currentCursor.x, out currentCursor.y);
        Vector2 delta = currentCursor - dragStartMouseWindows;
        Vector2 targetWindowPos = dragStartWindowPos + delta;

        // 可选阈值，避免极小移动导致的频繁更新（减少抖动）
        float sqrDist = (windowPosition - targetWindowPos).sqrMagnitude;
        if (sqrDist < 0.25f) // 小于 0.5 像素的平方则跳过
            return;

        // 设置窗口位置（Windows 坐标系）
        windowPosition = targetWindowPos;
    }

    // 结束拖拽：外部（Handle）调用
    public void EndWindowDrag()
    {
        isDragging = false;
    }

}